Better pal/sal support
authordjm@kirby.fc.hp.com <djm@kirby.fc.hp.com>
Tue, 12 Jul 2005 15:13:06 +0000 (08:13 -0700)
committerdjm@kirby.fc.hp.com <djm@kirby.fc.hp.com>
Tue, 12 Jul 2005 15:13:06 +0000 (08:13 -0700)
Fix bug with pgd allocation (used pgd_quick)
Add some more debug info for tracking down vcpu_translate bad addr
Signed-off by: Dan Magenheimer <dan.magenheimer@hp.com>

xen/arch/ia64/asm-offsets.c
xen/arch/ia64/dom_fw.c
xen/arch/ia64/hypercall.c
xen/arch/ia64/ivt.S
xen/arch/ia64/vcpu.c

index 43589b6586874bdd25b7470d1aba8f9f7b703c05..916ccc0fa635fb063981469f71fecb8bd2abc85e 100644 (file)
@@ -93,7 +93,7 @@ void foo(void)
 
        BLANK();
        DEFINE(IA64_CPUINFO_ITM_NEXT_OFFSET, offsetof (struct cpuinfo_ia64, itm_next));
-       DEFINE(IA64_CPUINFO_PGD_QUICK_OFFSET, offsetof (struct cpuinfo_ia64, pgd_quick));
+       DEFINE(IA64_CPUINFO_KSOFTIRQD_OFFSET, offsetof (struct cpuinfo_ia64, ksoftirqd));
 
        //DEFINE(IA64_SIGHAND_SIGLOCK_OFFSET,offsetof (struct sighand_struct, siglock));
 
index b57a727a501cb5e9368838f1bae8b9f5648274a1..a090006648e03b71560af5e01f1b6c1d9d181167 100644 (file)
@@ -154,7 +154,7 @@ offtime (unsigned long t, efi_time_t *tp)
        return 1;
 }
 
-extern void pal_emulator_static (void);
+extern struct ia64_pal_retval pal_emulator_static (unsigned long);
 
 /* Macro to emulate SAL call using legacy IN and OUT calls to CF8, CFC etc.. */
 
@@ -220,17 +220,14 @@ sal_emulator (long index, unsigned long in1, unsigned long in2,
         */
        status = 0;
        if (index == SAL_FREQ_BASE) {
-               switch (in1) {
+               if (!running_on_sim)
+                       status = ia64_sal_freq_base(in1,&r9,&r10);
+               else switch (in1) {
                      case SAL_FREQ_BASE_PLATFORM:
                        r9 = 200000000;
                        break;
 
                      case SAL_FREQ_BASE_INTERVAL_TIMER:
-                       /*
-                        * Is this supposed to be the cr.itc frequency
-                        * or something platform specific?  The SAL
-                        * doc ain't exactly clear on this...
-                        */
                        r9 = 700000000;
                        break;
 
@@ -285,6 +282,96 @@ sal_emulator (long index, unsigned long in1, unsigned long in2,
        return ((struct sal_ret_values) {status, r9, r10, r11});
 }
 
+struct ia64_pal_retval
+xen_pal_emulator(unsigned long index, unsigned long in1,
+       unsigned long in2, unsigned long in3)
+{
+       long r9  = 0;
+       long r10 = 0;
+       long r11 = 0;
+       long status = -1;
+
+       if (running_on_sim) return pal_emulator_static(index);
+       if (index >= PAL_COPY_PAL) {
+               printk("xen_pal_emulator: UNIMPLEMENTED PAL CALL %d!!!!\n",
+                               index);
+       }
+       else switch (index) {
+           case PAL_MEM_ATTRIB:
+               status = ia64_pal_mem_attrib(&r9);
+               break;
+           case PAL_FREQ_BASE:
+               status = ia64_pal_freq_base(&r9);
+               break;
+           case PAL_PROC_GET_FEATURES:
+               status = ia64_pal_proc_get_features(&r9,&r10,&r11);
+               break;
+           case PAL_BUS_GET_FEATURES:
+               status = ia64_pal_bus_get_features(&r9,&r10,&r11);
+               break;
+           case PAL_FREQ_RATIOS:
+               status = ia64_pal_freq_ratios(&r9,&r10,&r11);
+               break;
+           case PAL_PTCE_INFO:
+               status = ia64_get_ptce(&r9);
+               break;
+           case PAL_VERSION:
+               status = ia64_pal_version(&r9,&r10);
+               break;
+           case PAL_VM_PAGE_SIZE:
+               status = ia64_pal_vm_page_size(&r9,&r10);
+               break;
+           case PAL_DEBUG_INFO:
+               status = ia64_pal_debug_info(&r9,&r10);
+               break;
+           case PAL_CACHE_SUMMARY:
+               status = ia64_pal_cache_summary(&r9,&r10);
+               break;
+           case PAL_VM_SUMMARY:
+               status = ia64_pal_vm_summary(&r9,&r10);
+               break;
+           case PAL_RSE_INFO:
+               status = ia64_pal_rse_info(&r9,&r10);
+               break;
+           case PAL_VM_INFO:
+               status = ia64_pal_vm_info(in1,in2,&r9,&r10);
+               break;
+           case PAL_REGISTER_INFO:
+               status = ia64_pal_register_info(in1,&r9,&r10);
+               break;
+           case PAL_CACHE_FLUSH:
+               return pal_emulator_static(index); /* FIXME */
+               break;
+           case PAL_PERF_MON_INFO:
+               {
+                       unsigned long pm_buffer[16];
+                       status = ia64_pal_perf_mon_info(pm_buffer,&r9);
+                       if (status != 0) break;
+                       if (copy_to_user((void __user *)in1,pm_buffer,128))
+                               printk("xen_pal_emulator: PAL_PERF_MON_INFO "
+                                       "can't copy to user!!!!\n");
+               }
+               break;
+           case PAL_CACHE_INFO:
+               {
+                       pal_cache_config_info_t ci;
+                       status = ia64_pal_cache_config_info(in1,in2,&ci);
+                       if (status != 0) break;
+                       r9 = ci.pcci_info_1.pcci1_data;
+                       r10 = ci.pcci_info_2.pcci2_data;
+               }
+               break;
+           case PAL_VM_TR_READ:        /* FIXME: vcpu_get_tr?? */
+               break;
+           case PAL_HALT_INFO:         /* inappropriate info for guest? */
+               break;
+           default:
+               printk("xen_pal_emulator: UNIMPLEMENTED PAL CALL %d!!!!\n",
+                               index);
+               break;
+       }
+       return ((struct ia64_pal_retval) {status, r9, r10, r11});
+}
 
 #define NFUNCPTRS 20
 
index 84b05e850c7e915701ac1daafcf95ccf76fd0729..aecd0be174a2f0aad25514b382442b1cc25c0222 100644 (file)
@@ -16,7 +16,7 @@
 #include <asm/dom_fw.h>
 
 extern unsigned long translate_domain_mpaddr(unsigned long);
-extern struct ia64_sal_retval pal_emulator_static(UINT64);
+extern struct ia64_pal_retval xen_pal_emulator(UINT64,UINT64,UINT64,UINT64);
 extern struct ia64_sal_retval sal_emulator(UINT64,UINT64,UINT64,UINT64,UINT64,UINT64,UINT64,UINT64);
 
 unsigned long idle_when_pending = 0;
@@ -27,6 +27,7 @@ ia64_hypercall (struct pt_regs *regs)
 {
        struct vcpu *v = (struct domain *) current;
        struct ia64_sal_retval x;
+       struct ia64_pal_retval y;
        unsigned long *tv, *tc;
        int pi;
 
@@ -42,7 +43,6 @@ ia64_hypercall (struct pt_regs *regs)
                // in the idle loop, this should resolve it
                v->vcpu_info->arch.pending_interruption = 1;
 #endif
-               x = pal_emulator_static(regs->r28);
                if (regs->r28 == PAL_HALT_LIGHT) {
 #define SPURIOUS_VECTOR 15
                        pi = vcpu_check_pending_interrupts(v);
@@ -62,8 +62,15 @@ ia64_hypercall (struct pt_regs *regs)
                        }
                        //break;
                }
-               regs->r8 = x.status; regs->r9 = x.v0;
-               regs->r10 = x.v1; regs->r11 = x.v2;
+               else if (regs->r28 >= PAL_COPY_PAL) {   /* FIXME */
+                       printf("stacked PAL hypercalls not supported\n");
+                       regs->r8 = -1;
+                       break;
+               }
+               else y = xen_pal_emulator(regs->r28,regs->r29,
+                                               regs->r30,regs->r31);
+               regs->r8 = y.status; regs->r9 = y.v0;
+               regs->r10 = y.v1; regs->r11 = y.v2;
                break;
            case FW_HYPERCALL_SAL_CALL:
                x = sal_emulator(vcpu_get_gr(v,32),vcpu_get_gr(v,33),
index 6530783e67017945df857b3a03d72b5f18374509..1ac5593068184d8b194a1051b3ad52e566770e14 100644 (file)
@@ -931,10 +931,10 @@ ENTRY(interrupt)
        ;;
 #ifdef XEN
        mov r30=cr.ivr          // pass cr.ivr as first arg
-       // FIXME: this is a hack... use cpuinfo.pgd_quick because its
+       // FIXME: this is a hack... use cpuinfo.ksoftirqd because its
        // not used anywhere else and we need a place to stash ivr and
        // there's no registers available unused by SAVE_MIN/REST
-       movl r29=(PERCPU_ADDR)+IA64_CPUINFO_PGD_QUICK_OFFSET;;
+       movl r29=(PERCPU_ADDR)+IA64_CPUINFO_KSOFTIRQD_OFFSET;;
        st8 [r29]=r30;;
        movl r28=slow_interrupt;;
        mov r29=rp;;
@@ -954,7 +954,7 @@ slow_interrupt:
        ;;
        alloc r14=ar.pfs,0,0,2,0 // must be first in an insn group
 #ifdef XEN
-       movl out0=(PERCPU_ADDR)+IA64_CPUINFO_PGD_QUICK_OFFSET;;
+       movl out0=(PERCPU_ADDR)+IA64_CPUINFO_KSOFTIRQD_OFFSET;;
        ld8 out0=[out0];;
 #else
        mov out0=cr.ivr         // pass cr.ivr as first arg
index 57f721150c20f5c6c855c05a36eb0294f1007d87..985422b112b84111919a8ab00ad5ae0cd838ce6b 100644 (file)
@@ -1263,6 +1263,7 @@ IA64FAULT vcpu_ttag(VCPU *vcpu, UINT64 vadr, UINT64 *padr)
 #define itir_mask(itir) (~((1UL << itir_ps(itir)) - 1))
 
 unsigned long vhpt_translate_count = 0;
+int in_vcpu_tpa = 0;
 
 IA64FAULT vcpu_translate(VCPU *vcpu, UINT64 address, BOOLEAN is_data, UINT64 *pteval, UINT64 *itir)
 {
@@ -1271,8 +1272,20 @@ IA64FAULT vcpu_translate(VCPU *vcpu, UINT64 address, BOOLEAN is_data, UINT64 *pt
        ia64_rr rr;
 
        if (!(address >> 61)) {
-               if (!PSCB(vcpu,metaphysical_mode))
+               if (!PSCB(vcpu,metaphysical_mode)) {
+                       REGS *regs = vcpu_regs(vcpu);
+                       unsigned long viip = PSCB(vcpu,iip);
+                       unsigned long vipsr = PSCB(vcpu,ipsr);
+                       unsigned long iip = regs->cr_iip;
+                       unsigned long ipsr = regs->cr_ipsr;
+#if 0
+                       printk("vcpu_translate: bad address %p, viip=%p, vipsr=%p, iip=%p, ipsr=%p\n", address, viip, vipsr, iip, ipsr);
+                       if (in_vcpu_tpa) printk("vcpu_translate called from vcpu_tpa\n");
+                       while(1);
                        panic_domain(0,"vcpu_translate: bad address %p\n", address);
+#endif
+                       printk("vcpu_translate: bad address %p, viip=%p, vipsr=%p, iip=%p, ipsr=%p continuing\n", address, viip, vipsr, iip, ipsr);
+               }
 
                *pteval = (address & _PAGE_PPN_MASK) | __DIRTY_BITS | _PAGE_PL_2 | _PAGE_AR_RWX;
                *itir = PAGE_SHIFT << 2;
@@ -1291,6 +1304,7 @@ IA64FAULT vcpu_translate(VCPU *vcpu, UINT64 address, BOOLEAN is_data, UINT64 *pt
        /* check 1-entry TLB */
        if ((trp = match_dtlb(vcpu,address))) {
                dtlb_translate_count++;
+if (!in_vcpu_tpa) printf("vcpu_translate: found in vdtlb\n");
                *pteval = trp->page_flags;
                *itir = trp->itir;
                return IA64_NO_FAULT;
@@ -1342,7 +1356,9 @@ IA64FAULT vcpu_tpa(VCPU *vcpu, UINT64 vadr, UINT64 *padr)
        UINT64 pteval, itir, mask;
        IA64FAULT fault;
 
+in_vcpu_tpa=1;
        fault = vcpu_translate(vcpu, vadr, 1, &pteval, &itir);
+in_vcpu_tpa=0;
        if (fault == IA64_NO_FAULT)
        {
                mask = itir_mask(itir);